package day0116;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;

interface Enemy {
    int addScore();
}



interface Award {}

abstract class FlyObject {
    int x=0;
    int y=0;
    int speed=1;//Bee和飞机每次1像素
    abstract void move();
    abstract boolean outOfBounds();
    abstract BufferedImage getImg();
}

//蜜蜂的作用是给玩家奖励的(和Enemy接口没关系)
class Bee extends FlyObject implements Award {
    private static BufferedImage planeImg=null;

    public BufferedImage getImg() {
        return planeImg;
    }

    static {
        try {
            planeImg=ImageIO.read(MyGameTest.class.getResource("bee.png"));//工具类的read()
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    Bee()  {
        x= (int)(Math.random()*(MyGameTest.WIDTH-60));//bee.png 宽度是60像素
        y=0;
    }


    void move(){
        y= y +speed;
        x= x +speed;
    }

    boolean outOfBounds() {
        return y>MyGameTest.HEIGHT;
    }
}




class Hero extends FlyObject{
    private static BufferedImage beeImg=null;
    BufferedImage getImg() {
        return beeImg;
    }
    static {
        try {
            beeImg=ImageIO.read(MyGameTest.class.getResource("hero0.png"));//工具类的read()
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    Hero() {
        x=130;
        y=500;
    }


    int score=10;
    public int addScore(){//表示此飞机被消灭时，给玩家增加几分
        System.out.println("给玩家加10分");
        return score;
    }

    public void move(int x,  int y){
        this.y=y;
        this.x=x;
        //System.out.println("敌方小飞机正在移动,速度为" + speed);
    }

    void move() {}///////X

    boolean outOfBounds() { return false;  }///////X
}
























class SmallPlane extends FlyObject implements Enemy{
    private static BufferedImage beeImg=null;
    BufferedImage getImg() {
        return beeImg;
    }
    static {
        try {
            beeImg=ImageIO.read(MyGameTest.class.getResource("airplane.png"));//工具类的read()
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    SmallPlane() {
        x= (int)(Math.random()*(MyGameTest.WIDTH-50));//airplane.png 宽度是50像素
        y=0;
    }

    boolean outOfBounds() {
        return y>MyGameTest.HEIGHT;
    }

    int score=10;
    public int addScore(){//表示此飞机被消灭时，给玩家增加几分
        System.out.println("给玩家加10分");
        return score;
    }

    public void move(){
        y=y+speed;
        //System.out.println("敌方小飞机正在移动,速度为" + speed);
    }
}




public class MyGameTest  extends  JPanel{//游戏的主程序： 包含逻辑性的代码  //纸
    public static final int WIDTH=420;
    public static final int HEIGHT=700;//界面的总高度。  //MyGameTest.HEIGHT

    int createInterval=1;
    FlyObject[]  flys=new FlyObject[0];//1.定义一个FlyObject[] flys=new FlyObject[0];
    //2.定义一个createObjs(){}，根据随机数的范围创建不同的对象存入到flys数组的最后一位。
    private void createObjs() {
        if(createInterval%40 ==0 ){
            int num=(int)(Math.random()*100);
            if(0<num&& num<50){//创建Bee放入flys数组最后一个位置
                Bee b=new Bee();
                flys=Arrays.copyOf(flys, flys.length+1);//将数组扩容出一个新空间
                flys[flys.length-1]=b;
            }else{//创建飞机放入flys数组最后一个位置
                SmallPlane b= new SmallPlane();
                flys=Arrays.copyOf(flys, flys.length+1);//将数组扩容出一个新空间
                flys[flys.length-1]=b;
            }
        }
        createInterval++;
    }

    public void stepAction(){//让flys数组的每个元素移动一次。
        for (int i = 0; i <flys.length ; i++) {
            FlyObject f=flys[i];//取出数组的元素
            f.move();//调用元素的move()： 让元素的坐标去改变
        }
    }

    public void outOfBoundsAction(){//判断所有元素是否越界
        //判断数组的每个元素是否超出游戏的下边界
        for (int i = 0; i < flys.length; i++) {
            FlyObject fly=flys[i];
            boolean isOut=fly.outOfBounds();
            if(isOut==true){
                for (int j = i; j <flys.length-1 ; j++) {
                    flys[j]= flys[j+1];
                }//从数组中删除第i个元素。
                flys=Arrays.copyOf(flys, flys.length-1);
            }
        }
        //用for循环从fly数组中取出一个元素，调用这个元素的的outOfBounds()，判断这个元素是否越界
        //                                          判断一个元素是否越界
    }

    static BufferedImage bgImg=null;
    static {
        try {
            bgImg=ImageIO.read(MyGameTest.class.getResource("bg.png"));//工具类的read()
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //画图片的第一步：读取图片(背景图)
    MyGameTest() throws IOException {    //MyGameTest.class.getResource: 获取路径
        //1.用MouseAdapter创建一个鼠标监听器 new (){   监听鼠标移动的方法 }
        MouseAdapter mouseAda=new MouseAdapter() {
            public void mouseMoved(MouseEvent e) {
                //让hero的坐标移动到  e.getX(), e.getY() 坐标位置(鼠标的坐标处)。
                //hero.move(e.getX()-hero飞机图片宽度/2, e.getY()-hero飞机图片高度/2);//触发执行的代码  改变hero的坐标  move(鼠标x，  鼠标的y)
                hero.move(e.getX()-97/2, e.getY()-139/2);//触发执行的代码  改变hero的坐标  move(鼠标x，  鼠标的y)
            }
        };
        //2.将鼠标监听器设置给面板
        this.addMouseListener(mouseAda);//this//代表当前MyGameTest面板类对象
        this.addMouseMotionListener(mouseAda);//监听鼠标移动的
        this.setFocusable(true);//3.让面板能获取焦点
        this.requestFocus();//让面板获取焦点
    }


    Hero hero=new Hero();
    //画图片的第二步： 调用paint()方法绘制图片到面板上
    //paint()方法在创建面板对象的时候  "new MyGameTest()"  (MyGameTest继承了面板类JPanel类)会自动执行
    //4.将图片绘制到面板上(画到纸上)
    public void paint(Graphics g){//创建面板对象的时候 paint()方法 会自动执行是java提供的JPanel类中的代码
        //背景图
        g.drawImage(bgImg,0,0,null);
        g.drawImage(hero.getImg(),hero.x,hero.y,null);
        //文字信息
        //所有的敌方飞机和蜜蜂
        for (int i = 0; i < flys.length; i++) {
            BufferedImage flyImg=flys[i].getImg();
            g.drawImage(flyImg,  flys[i].x, flys[i].y,null);
        }
        //子弹
        //自己也画出来
    }


    public static void main(String[] args) throws Exception {
        //JFrame类。
        JFrame win = new JFrame("飞机大战");//电脑内存中(默认是隐藏)//1.桌子


        //创建MyGmeTest面板对象的时候会自动执行paint()方法
        MyGameTest game=new MyGameTest();//2.纸
        win.add(game);//3.桌子上放一张纸

        win.setSize(WIDTH,HEIGHT);
        win.setVisible(true);//设置i窗口对象win是否像是

        //int index=1;
        while(true){
            //main执行每隔800号码会给flys中放入一个元素
            game.createObjs();//1.
            game.stepAction();//2.调用flys数组每个元素的move()让数组元素都自动往前走一下//打印数组长度，用来检查createObjs()在不断给flys数组中添加元素。
            game.outOfBoundsAction();
            //可以看到每隔800毫秒就会增加一个新元素
            Thread.sleep(80);// 每次移动1像素  10*900   //等9000毫秒发现数组少一个元素
            //index++;
            //repaint(g); //将游戏中所有的对象重新画到界面
            game.repaint();
        }
    }




/*
    void shooted(day0115.game.FlyObject obj){// FlyObject  plane=new SmallPlane();
        if(obj instanceof day0115.game.Award){
            System.out.println("给玩家奖励双倍子弹");
        }else if(obj instanceof day0115.game.Enemy){
            day0115.game.Enemy e=(day0115.game.Enemy)obj;
            e.addScore();//调用敌方对象的添加分数方法
        }
    }
*/



}












